package com.efounder.utils;

import android.Manifest;
import android.app.Activity;
import android.app.AppOpsManager;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Binder;
import android.os.Build;
import android.provider.Settings;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;
import android.text.TextUtils;
import android.view.View;
import android.view.WindowManager;

import com.efounder.thirdpartycomps.R;
import com.utilcode.util.ActivityUtils;
import com.utilcode.util.SPUtils;

import java.lang.reflect.Method;

import pub.devrel.easypermissions.EasyPermissions;
import pub.devrel.easypermissions.PermissionRequest;

/**
 * 基于easypermission动态请求的权限
 * Created by yqs on 2018/07/19.
 * <p/>
 * 这些权限需要动态申请：
 * ACCESS_COARSE_LOCATION、 ACCESS_FINE_LOCATION、 ADD_VOICEMAIL、 BODY_SENSORS
 * CALL_PHONE、 CAMERA、 GET_ACCOUNTS、 PROCESS_OUTGOING_CALLS、READ_CALENDAR
 * READ_CALL_LOG、 READ_CELL_BROADCASTS、 READ_CONTACTS、 READ_EXTERNAL_STORAGE
 * READ_PHONE_STATE、READ_SMS、RECEIVE_MMS、RECEIVE_SMS、RECEIVE_WAP_PUSH、RECORD_AUDIO
 * SEND_SMS、USE_SIP、WRITE_CALENDAR、WRITE_CALL_LOG、WRITE_CONTACTS、WRITE_EXTERNAL_STORAGE
 */
public class EasyPermissionUtils {

    /**
     * 读SDCARD 权限
     */
    public static final int PERMISSION_WRITE_EXTERNAL_STORAGE_REQUEST_CODE = 51;

    /**
     * 定位权限
     */
    public static final int PERMISSION_REQUEST_CODE_LOCATION = 52;

    /**
     * 录音权限
     */
    public static final int PERMISSION_REQUEST_CODE_AUDIO = 53;

    /**
     * 照相机权限
     */
    public static final int PERMISSION_REQUEST_CODE_CAMERA = 54;

    public static final int PERMISSION_REQUEST_CODE_CAMERA_AND_AUDIO = 55;

    /**
     * 读取手机状态权限（for imei）
     */
    public static final int PERMISSION_REQUEST_CODE_READ_PHONE_STATE = 56;

    public static final int PERMISSION_REQUEST_CODE_INIT = 57;
    /**
     * 读取通讯录权限
     */
    public static final int PERMISSION_CODE_READ_CONTACT = 58;

    /**
     * 悬浮窗权限
     */
    public static final int PERMISSION_OVER_LAY = 59;

    /**
     * 检查写权限
     *
     * @param
     */
    public static boolean checkWritePermission() {
        Activity context = ActivityUtils.getTopActivity();
        return EasyPermissions.hasPermissions(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    }

    /**
     * 检查写以及获取设备信息权限
     *
     * @param
     */
    public static boolean checkWriteAndPhonePermission() {
        Activity activity = ActivityUtils.getTopActivity();
        if (activity == null) {
            return false;
        }
        return checkWriteAndPhonePermission(activity);
    }

    public static boolean checkWriteAndPhonePermission(Activity activity) {
        //这里我们判断一下，如果支持移动安全联盟设备标识符i获取，那我们就不在请求READ_PHONE_STATE权限，因为此权限获取敏感
        if (supportMittDeviceId()) {
            return EasyPermissions.hasPermissions(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        } else {
            return EasyPermissions.hasPermissions(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE);
        }
    }

    /**
     * 检查定位权限
     */
    public static boolean checkLocationPermission() {
        Activity context = ActivityUtils.getTopActivity();
        return EasyPermissions.hasPermissions(context, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION);
    }

    /**
     * 检查读取通讯录权限
     */
    public static boolean checkReadContactPermission() {
        Activity context = ActivityUtils.getTopActivity();
        return EasyPermissions.hasPermissions(context, Manifest.permission.READ_CONTACTS);
    }

    /**
     * 照相机权限
     */
    public static boolean checkCameraPermission() {
        Activity context = ActivityUtils.getTopActivity();
        return EasyPermissions.hasPermissions(context, Manifest.permission.CAMERA);

    }

    /**
     * 检查录音权限
     */
    public static boolean checkAudioPermission() {
        Activity context = ActivityUtils.getTopActivity();
        return EasyPermissions.hasPermissions(context, Manifest.permission.RECORD_AUDIO);
    }

    /**
     * 检查直播需要的相机和麦克风权限
     */
    public static boolean checkRecordVideoPermission() {
        Activity context = ActivityUtils.getTopActivity();
        return EasyPermissions.hasPermissions(context, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO);
    }

    /**
     * 检查获取手机imei
     *
     * @param
     * @return
     */
    public static boolean checkReadPhoneStatePermission() {
        Activity context = ActivityUtils.getTopActivity();
        return EasyPermissions.hasPermissions(context, Manifest.permission.READ_PHONE_STATE);

    }


    /**
     * 检查是否具有悬浮窗权限
     *
     * @param
     * @return
     */
    public static boolean checkOverLayPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return Settings.canDrawOverlays(ActivityUtils.getTopActivity());
        } else {
            return hasPermissionBelowMarshmallow(ActivityUtils.getTopActivity());
        }
    }

    /**
     * 设置接面设置完之后判断
     *
     * @param context
     * @return
     */
    static boolean hasOverLayPermissionPermissionOnActivityResult(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            return hasPermissionForO(context);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return Settings.canDrawOverlays(context);
        } else {
            return hasPermissionBelowMarshmallow(context);
        }
    }

    /**
     * 6.0以下判断是否有权限
     * 理论上6.0以上才需处理权限，但有的国内rom在6.0以下就添加了权限
     * 其实此方式也可以用于判断6.0以上版本，只不过有更简单的canDrawOverlays代替
     */
    static boolean hasPermissionBelowMarshmallow(Context context) {
        try {
            AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
            Method dispatchMethod = AppOpsManager.class.getMethod("checkOp", int.class, int.class, String.class);
            //AppOpsManager.OP_SYSTEM_ALERT_WINDOW = 24
            return AppOpsManager.MODE_ALLOWED == (Integer) dispatchMethod.invoke(
                    manager, 24, Binder.getCallingUid(), context.getApplicationContext().getPackageName());
        } catch (Exception e) {
            return false;
        }
    }


    /**
     * 用于判断8.0时是否有权限，仅用于OnActivityResult
     * 针对8.0官方bug:在用户授予权限后Settings.canDrawOverlays或checkOp方法判断仍然返回false
     */
    private static boolean hasPermissionForO(Context context) {
        try {
            WindowManager mgr = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            if (mgr == null) {
                return false;
            }
            View viewToAdd = new View(context);
            WindowManager.LayoutParams params = new WindowManager.LayoutParams(0, 0,
                    android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O ?
                            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                    WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                    PixelFormat.TRANSPARENT);
            viewToAdd.setLayoutParams(params);
            mgr.addView(viewToAdd, params);
            mgr.removeView(viewToAdd);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    /**
     * 请求读取通讯录权限
     *
     * @param activity
     */
    public static void requestReadContactPermission(Activity activity) {
        requestPermission(activity, R.string.permission_read_contact,
                PERMISSION_CODE_READ_CONTACT, Manifest.permission.READ_CONTACTS);

    }

    /**
     * 请求读取通讯录权限
     *
     * @param fragment
     */
    public static void requestReadContactPermission(Fragment fragment) {
        requestPermission(fragment, R.string.permission_read_contact,
                PERMISSION_CODE_READ_CONTACT, Manifest.permission.READ_CONTACTS);

    }

    /**
     * 请求存储以及设备信息权限
     *
     * @param activity
     */
    public static void requestStorageAndPhoneStatePermission(Activity activity) {
        //这里我们判断一下，如果支持移动安全联盟设备标识符i获取，那我们就不在请求READ_PHONE_STATE权限，因为此权限获取敏感
        if (supportMittDeviceId()) {
            requestPermission(activity, R.string.permission_write_stroge_phone_state,
                    PERMISSION_WRITE_EXTERNAL_STORAGE_REQUEST_CODE, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        } else {
            requestPermission(activity, R.string.permission_write_stroge_phone_state,
                    PERMISSION_WRITE_EXTERNAL_STORAGE_REQUEST_CODE, Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.READ_PHONE_STATE);
        }


    }

    /**
     * 请求存储以及设备信息权限
     *
     * @param fragment
     */
    public static void requestStorageAndPhoneStatePermission(Fragment fragment) {
        //这里我们判断一下，如果支持移动安全联盟设备标识符i获取，那我们就不在请求READ_PHONE_STATE权限，因为此权限获取敏感
        if (supportMittDeviceId()) {
            requestPermission(fragment, R.string.permission_write_stroge_phone_state,
                    PERMISSION_WRITE_EXTERNAL_STORAGE_REQUEST_CODE, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        } else {
            requestPermission(fragment, R.string.permission_write_stroge_phone_state,
                    PERMISSION_WRITE_EXTERNAL_STORAGE_REQUEST_CODE, Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.READ_PHONE_STATE);
        }

    }

    /**
     * 请求拍摄视频权限
     *
     * @param activity
     */
    public static void requestRecordVideoPermission(Activity activity) {
        requestPermission(activity, R.string.permission_record_video, PERMISSION_REQUEST_CODE_CAMERA_AND_AUDIO, Manifest.permission.CAMERA,
                Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    }

    /**
     * 请求拍摄视频权限
     *
     * @param fragment
     */
    public static void requestRecordVideoPermission(Fragment fragment) {
        requestPermission(fragment, R.string.permission_record_video, PERMISSION_REQUEST_CODE_CAMERA_AND_AUDIO, Manifest.permission.CAMERA,
                Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    }

    /**
     * 请求拍照权限
     *
     * @param fragment
     */
    public static void requestCameraPermission(Fragment fragment) {
        requestPermission(fragment, R.string.permission_camera, PERMISSION_REQUEST_CODE_CAMERA, Manifest.permission.CAMERA);

    }

    /**
     * 请求拍照权限
     *
     * @param activity
     */
    public static void requestCameraPermission(Activity activity) {
        requestPermission(activity, R.string.permission_camera, PERMISSION_REQUEST_CODE_CAMERA, Manifest.permission.CAMERA);
    }

    /**
     * 请求录音权限
     *
     * @param activity
     */
    public static void requestAudioPermission(Activity activity) {
        requestPermission(activity, R.string.permission_record_voice, PERMISSION_REQUEST_CODE_AUDIO, Manifest.permission.RECORD_AUDIO);
    }

    /**
     * 请求录音权限
     *
     * @param fragment
     */
    public static void requestAudioPermission(Fragment fragment) {
        requestPermission(fragment, R.string.permission_record_voice, PERMISSION_REQUEST_CODE_AUDIO, Manifest.permission.RECORD_AUDIO);
    }

    /**
     * 请求定位权限
     *
     * @param activity
     */
    public static void requestLocationPermission(Activity activity) {
        requestPermission(activity, R.string.permission_location, PERMISSION_REQUEST_CODE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION);
    }

    /**
     * 请求定位权限
     *
     * @param fragment
     */
    public static void requestLocationPermission(Fragment fragment) {
        requestPermission(fragment, R.string.permission_location, PERMISSION_REQUEST_CODE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION);
    }


    private static void requestPermission(Activity activity, @StringRes int stringId, int requestCode, String... param) {
        EasyPermissions.requestPermissions(
                new PermissionRequest.Builder(activity, requestCode, param)
                        .setRationale(stringId)
                        .setPositiveButtonText(R.string.common_text_confirm)
                        .setNegativeButtonText(R.string.common_text_cancel)
                        .build());
    }

    private static void requestPermission(Fragment fragment, @StringRes int stringId, int requestCode, String... param) {
        EasyPermissions.requestPermissions(
                new PermissionRequest.Builder(fragment, requestCode, param)
                        .setRationale(stringId)
                        .setPositiveButtonText(R.string.common_text_confirm)
                        .setNegativeButtonText(R.string.common_text_cancel)
                        .build());
    }

    /**
     * 是否支持移动安全联盟设备标识符获取
     *
     * @return
     */
    private static boolean supportMittDeviceId() {
        SPUtils spUtils = SPUtils.getInstance("EnvironmentVariable");
        //支持唯一id获取并且oaid不是空
        if (spUtils != null && spUtils.getString("supportMiit", "").equals("1")
                && !TextUtils.isEmpty(spUtils.getString("miitOAID", ""))) {
            return true;
        } else {
            return false;
        }
    }
}